/** file AudioWAV.cpp
    author belot.nicolas
*/

#include "AudioWAV.h"
#include <iostream>

namespace libtrckr {

AudioWAV::AudioWAV(){
	_sfinfo=(struct SF_INFO*)malloc(sizeof(struct SF_INFO));
	_sfinfo->format = SF_FORMAT_WAV | SF_FORMAT_PCM_24;
	_state = INVALID;
}

AudioWAV::AudioWAV(const AudioWAV& aw){
	_sfinfo=(struct SF_INFO*)malloc(sizeof(struct SF_INFO));
	memcpy(_sfinfo,aw._sfinfo, sizeof(struct SF_INFO));
	channels(aw.channels());
	bitrate(aw.bitrate());
	if(aw._state!=INVALID)
		_state=CLOSE;
	else
		_state=INVALID;
}

AudioWAV::~AudioWAV( ){
	free(_sfinfo);
}

void AudioWAV::channels(int chan){
	_sfinfo->channels=chan;
}

int AudioWAV::channels() const{
	return _sfinfo->channels;
}

void AudioWAV::bitrate(int br){
	_sfinfo->samplerate=br;
}

int AudioWAV::bitrate() const {
	return _sfinfo->samplerate;
}

void AudioWAV::open(){
	if(sf_format_check(_sfinfo)){
		_handler=sf_open(filename.c_str(),SFM_WRITE, _sfinfo);
		if(_handler!=NULL) _state=OPEN;
		else _state=INVALID;
	}else{
		_state=INVALID;
	}
}

Audio::audio_state_t AudioWAV::state(){
	return _state;
}

void AudioWAV::close(){
	if(_state==OPEN){
		if(sf_close(_handler)==0){
			_state=CLOSE;
		}else{
			_state=INVALID;
		}
	}
}

void AudioWAV::param(std::string name, std::string value){
	if(name=="filename"){
		filename=value;
	}else{
		std::cerr << "No string param  named " << name <<std::endl;
	}
}	
void AudioWAV::param(std::string name, double value){
	std::cerr << "No double param  named " << name <<std::endl;
}
void AudioWAV::param(std::string name, int value){
	std::cerr << "No int param  named " << name <<std::endl;
}

int AudioWAV::append(Buffer b){
	if(_state==OPEN){
		if(b.channels()==channels()){
			return sf_writef_double(_handler,b.getContent(),b.size() );
		}else if(b.channels() < channels()){
			int count=b.channels();
			b.channels(channels());
			if(count ==1 && channels()==2){
				double tmp;
				/*mono to stereo...as we can't know spatial repartition...
				left=50% right=50%*/
				for(uint i=0;i<b.size();i++){
					b.setChannel(0);
					tmp=b[i]/=2.0;
					b.setChannel(1);
					b[i]=tmp;
				}
			}
			return sf_writef_double(_handler,b.getContent(),b.size());
		}else{
			Buffer b2=Buffer(b.size());
			b2.channels(channels());
			if(b.channels()==2 && channels()==1){
				for(uint i=0;i<b.size();i++){
					b.setChannel(0);
					b2[i]=b[i];
					b.setChannel(1);
					b2[i]+=b[i];
					b2[i]/=2;
				}
				return sf_writef_double(_handler,b2.getContent(),b.size());
			}
		}
	}
}

}
